const express = require('express')
const fs = require('fs')
const { clients } = require('../../service/websocket_service')
const db = require('../../db')
const ffmpeg = require('fluent-ffmpeg')
const ffmpegPath = require('ffmpeg-static')
const ffprobeStatic = require('ffprobe-static');
const crypto = require('crypto')
const path = require('path')
const router = express.Router()

ffmpeg.setFfmpegPath(ffmpegPath)
ffmpeg.setFfprobePath(ffprobeStatic.path)

const TEMP_DIR = path.join(__dirname, 'temp')
const UPLOAD_DIR = path.join(__dirname, 'uploads')

router.post('/', async (req, res) => {
  const { uploadId, fileName, fileType, sender_id, receiver_id } = req.query
  // console.log(req.query)

  try {
    const tempDir = path.join(TEMP_DIR, uploadId)
    const chunkDir = path.join(tempDir, 'chunks')
    
    // 验证所有分片是否已上传
    const chunks = fs.readdirSync(chunkDir)
    if (chunks.length === 0) {
      return res.errHandle('没有找到文件')
    }
    
    // 合并文件
    const finalFileName = `${uploadId}-${Date.now()}${path.extname(fileName)}`
    const finalPath = path.join(UPLOAD_DIR, finalFileName)

    const resultHash = await mergeChunks({
      chunkDir,
      finalPath,
      uploadId,
      tempDir,
      chunkCount: chunks.length,
      originalFileName: fileName
    })

    // console.log('resultHash: ', resultHash)

    if (resultHash === uploadId) {
      const _type = (fileType.split('/'))[0]
      // console.log(_type)

      const min_name = 'min_' + finalFileName
      let message_type = 5 // 文件

      if (_type === 'video') {
        message_type = 4 // 视频
        // 生成缩略图
        ffmpeg(finalPath)
        .screenshots({
          timestamps: ['1%'],
          filename: min_name.split('.')[0] + '.png',
          folder: UPLOAD_DIR,
          size: '1080x?'
        })
        .on('end', () => console.log('视频缩略图生成完成'))
        .on('error', err => console.error('错误:', err))
      } else if (_type === 'image') {
        message_type = 2 // 图片

        ffmpeg(finalPath)
        .size('320x?')
        .output(path.join(UPLOAD_DIR, min_name))
        .on('end', () => console.log('图片缩略图生成完成'))
        .on('error', err => console.error('错误:', err))
        .run()
      }
      
      const setData = 'insert into easy_chat.messages set ?'
      db.query(setData, { sender_id, receiver_id, message_type, content: finalFileName }, (err, result) => {
        if (err) res.errHandle(err)

        const sendMessageToUser = () => {
          const sender = clients.get(sender_id)
          const receiver = clients.get(receiver_id)
          // console.log(sender)
          const message = {
            code: 200,
            message: 'success',
            type: 'message',
            data: {
              message_id: result.insertId,
              sender_id,
              receiver_id,
              message_type,
              content: result.insertId,
              is_read: 0
            }
          }
          if (sender) {
            try {
              sender.send(JSON.stringify(message))
            } catch (error) {
              console.error(`发送消息给用户 ${sender_id} 时出错:`, error)
            }
          }
          if (receiver) {
            try {
              receiver.send(JSON.stringify(message))
            } catch (error) {
              console.error(`发送消息给用户 ${receiver_id} 时出错:`, error)
            }
          }
        }

        // 延时通知用户
        setTimeout(() => {
          sendMessageToUser()
        }, 2000)

        res.send({
          code: 200,
          message: 'success',
          data: {
            message_id: result.insertId,
            sender_id,
            receiver_id,
            message_type,
            content: result.insertId,
            is_read: 0
          }
        })

        // const giveMinimg = () => {
        //   const selectImg = 'select content from easy_chat.messages where message_id = ?'
        //   db.query(selectImg, result.insertId, (error, data) => {
        //     if (err) {
        //       giveMinimg()
        //     }
        //     sendMessageToUser(sender_id)
        //   })
        // }
        // giveMinimg()
      })
    } else {
      res.send({
        code: 200,
        message: 'fail',
        data: {
          message: '文件上传不完整'
        }
      })
    }
    
    // 清理临时文件
    fs.rmSync(tempDir, { recursive: true })

  } catch (err) {
    console.error('合并文件失败:', err)
    res.send({
      code: 400,
      message: 'fail'
    })
  }
})

// 合并分片函数
const mergeChunks = async ({ chunkDir, finalPath, chunkCount, uploadId, tempDir }) => {
  return new Promise((resolve, reject) => {
    const writeStream = fs.createWriteStream(finalPath)
    
    // 按顺序合并分片
    let currentChunk = 0
    
    const writeNextChunk = () => {
      // if (currentChunk === 1) {
      //   currentChunk++
      //   writeNextChunk()
      // }
      const chunkPath = path.join(chunkDir, `chunk-${currentChunk}`)
      
      const readStream = fs.createReadStream(chunkPath)
      
      readStream.pipe(writeStream, { end: false })
      
      readStream.on('end', () => {
        currentChunk++
        if (currentChunk < chunkCount) {
          writeNextChunk()
        } else {
          writeStream.end()
        }
      })
      
      readStream.on('error', (err) => {
        writeStream.close()
        reject(err)
      })
    }
    
    writeNextChunk()

    writeStream.on('finish', () => {
      // 创建哈希对象
      const hash = crypto.createHash('md5')
      const stream = fs.createReadStream(finalPath)

      stream.on('data', (data) => {
        hash.update(data)
      })

      stream.on('end', () => {
        const finalHash = hash.digest('hex')
        if (finalHash !== uploadId) {
          // fs.rmSync(tempDir, { recursive: true })
          fs.rmSync(finalPath, { recursive: true })
        }
        resolve(finalHash)
      })

      stream.on('error', (error) => {
        reject(error)
      })
    })
  })
}

module.exports = router
